<?php
namespace app\apijson\query\operators;

class WithOperator
{
    public static function apply($query, $value)
    {
        // 支持 JSON 格式的关联配置
        if (is_string($value)) {
            // 尝试解析 JSON
            $decoded = json_decode($value, true);
            if (json_last_error() === JSON_ERROR_NONE && is_array($decoded)) {
                self::processJsonWith($query, $decoded);
                return;
            }
        }
        
        // 支持 ['user:id,name', ...] 形式或字符串格式 "user:id,name|xxx:aaa,bbb"
        if (is_array($value)) {
            foreach ($value as $withItem) {
                self::processWithItem($query, $withItem);
            }
        } elseif (is_string($value)) {
            // 支持字符串格式：user:id,name|xxx:aaa,bbb
            if (strpos($value, '|') !== false) {
                $withItems = explode('|', $value);
                foreach ($withItems as $withItem) {
                    $withItem = trim($withItem);
                    self::processWithItem($query, $withItem);
                }
            } else {
                // 单个关联
                self::processWithItem($query, $value);
            }
        }
    }

    private static function processJsonWith($query, $config)
    {
        foreach ($config as $relation => $relationConfig) {
            if (isset($relationConfig['fields']) && is_array($relationConfig['fields'])) {
                $fields = $relationConfig['fields'];
                
                // 检查是否有嵌套关联
                if (isset($relationConfig['with']) && is_array($relationConfig['with'])) {
                    // 有嵌套关联，递归处理
                    $query->with([
                        $relation => function($q) use ($fields, $relationConfig) {
                            $q->select($fields);
                            
                            // 递归处理嵌套关联
                            self::processNestedWith($q, $relationConfig['with']);
                        }
                    ]);
                } else {
                    // 普通关联
                    $query->with([
                        $relation => function($q) use ($fields) {
                            $q->select($fields);
                        }
                    ]);
                }
            }
        }
    }

    private static function processNestedWith($query, $nestedConfig)
    {
        foreach ($nestedConfig as $relation => $relationConfig) {
            if (isset($relationConfig['fields']) && is_array($relationConfig['fields'])) {
                $fields = $relationConfig['fields'];
                
                // 检查是否有更深层的嵌套关联
                if (isset($relationConfig['with']) && is_array($relationConfig['with'])) {
                    // 有更深层的嵌套关联，递归处理
                    $query->with([
                        $relation => function($q) use ($fields, $relationConfig) {
                            $q->select($fields);
                            
                            // 递归处理更深层的嵌套关联
                            self::processNestedWith($q, $relationConfig['with']);
                        }
                    ]);
                } else {
                    // 当前层级的普通关联
                    $query->with([
                        $relation => function($q) use ($fields) {
                            $q->select($fields);
                        }
                    ]);
                }
            }
        }
    }

    private static function processWithItem($query, $withItem)
    {
        if (strpos($withItem, ':') !== false) {
            [$relation, $fields] = explode(':', $withItem, 2);
            $relation = trim($relation);
            
            // 支持点结构的嵌套关联查询，如 mak.maker
            if (!preg_match('/^[a-zA-Z_][a-zA-Z0-9_.]*$/', $relation)) {
                throw new \app\apijson\core\ApiJsonException('非法关联名: ' . $relation);
            }
            
            $fieldsArr = array_map('trim', explode(',', $fields));
            foreach ($fieldsArr as $f) {
                if (!preg_match('/^[a-zA-Z_][a-zA-Z0-9_.*]*$/', $f)) {
                    throw new \app\apijson\core\ApiJsonException('非法关联字段: ' . $f);
                }
            }
            
            // 处理嵌套关联查询
            if (strpos($relation, '.') !== false) {
                // 使用 Laravel 的嵌套关联语法
                $relations = explode('.', $relation);
                $nestedWith = [];
                $current = &$nestedWith;
                
                // 构建嵌套关联数组
                for ($i = 0; $i < count($relations) - 1; $i++) {
                    $current[$relations[$i]] = [];
                    $current = &$current[$relations[$i]];
                }
                
                // 最后一个关联添加字段选择
                $current[$relations[count($relations) - 1]] = function($q) use ($fieldsArr) {
                    $q->select($fieldsArr);
                };
                
                $query->with($nestedWith);
            } else {
                // 普通关联查询
                $query->with([$relation => function($q) use ($fieldsArr) {
                    $q->select($fieldsArr);
                }]);
            }
        } else {
            // 支持点结构的关联名
            if (!preg_match('/^[a-zA-Z_][a-zA-Z0-9_.*]*$/', $withItem)) {
                throw new \app\apijson\core\ApiJsonException('非法关联名: ' . $withItem);
            }
            $query->with($withItem);
        }
    }
}